package com.xdf.whiteaccount.config.properties;

import com.zaxxer.hikari.HikariDataSource;
import lombok.Builder;
import lombok.Data;
import lombok.experimental.Tolerate;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @program: white-account
 * @description: 数据库配置
 * @author: 张柯
 * @create: 2021-06-11 10:22
 **/
@Data
@Builder
@Component
@ConfigurationProperties(prefix = "dbconfig.datasource")
public class DbConfig {
    private String name;
    private String port;
    private String host;
    private String driverClassName;
    private String username;
    private String password;
    private String url;
    private int initializationFailTimeout;
    private int loginTimeout;
    private long idleTimeout;
    private int minimumIdle;
    private long connectionTimeout;
    private long maxLifeTime;
    private int maximumPoolSize;
    private int initialSize;
    private String validationQuery;
    private boolean testOnBorrow;
    private long timeBetweenEvictionRunsMillis;
    private int minEvictableIdleTimeMillis;
    private Map<String, String> jdbcUrlParam;

    @Tolerate
    public DbConfig() {
    }

    /**
     * 获取连接
     *
     * @param database
     * @return
     */
    public String getJdbcUrl(String database) {
        Map<String, String> defaultParam = new HashMap<>();
        defaultParam.put("useUnicode", "true");
        defaultParam.put("serverTimezone", "Asia/Shanghai");
        defaultParam.put("characterEncoding", "UTF-8");
        defaultParam.put("allowMultiQueries", "true");
        String urlTemplate = "jdbc:mysql://{0}:{1}/{2}?{3}";
        if (jdbcUrlParam != null && jdbcUrlParam.size() > 0) {
            defaultParam.putAll(jdbcUrlParam);
        }
        return MessageFormat.format(urlTemplate, this.host, this.port, database, createLinkStringByMap(defaultParam));
    }

    private String createLinkStringByMap(Map<String, String> map) {
        return map.keySet().stream().map(item -> item + "=" + map.get(item)).collect(Collectors.joining("&"));
    }

    /**
     * 创建数据源
     *
     * @param dbConfig
     * @return
     */
    public static HikariDataSource getDataSource(DbConfig dbConfig) {
        synchronized (DbConfig.class) {
            HikariDataSource ds = new HikariDataSource();
            ds.setDriverClassName(dbConfig.getDriverClassName());
            ds.setJdbcUrl(dbConfig.getUrl());
            ds.setUsername(dbConfig.getUsername());
            ds.setPassword(dbConfig.getPassword());
            ds.setValidationTimeout(dbConfig.getConnectionTimeout());
            ds.setConnectionTimeout(dbConfig.getConnectionTimeout());
            ds.setMaximumPoolSize(dbConfig.getMaximumPoolSize());
            ds.setMaxLifetime(dbConfig.getMaxLifeTime());
            ds.setMinimumIdle(dbConfig.getMinimumIdle());
            ds.setConnectionTestQuery(dbConfig.getValidationQuery());
            ds.setIdleTimeout(dbConfig.getIdleTimeout());
            ds.setInitializationFailTimeout(dbConfig.getInitializationFailTimeout());
            return ds;
        }
    }
}
